#include "GowildProtocol.h"

GowildProtocol::GowildProtocol(QObject *parent) :
    BaseProtocol(parent)
{
    this->m_protocolType = ProtocolType::GowildProtocol;
}

QList<Package> GowildProtocol::parseData(QByteArray data)
{
    CheckSteps checkSteps = CHECK_HEAD;  //当前解析状态
    quint16  lengthCount = 0;      //数据长度计算
    quint16 dataLength = 0;
    QByteArray dataArray;
    QList<Package> packageList;
    bool isParseSucceed = false;

    for(int i=0; i<data.size(); i++)
    {
        quint8 byte = data.at(i);
        switch(checkSteps)
        {
            case CHECK_HEAD:   //检查数据头
                 if(byte == 0XAA)
                 {
                     lengthCount = 0;
                     dataLength = 0;
                     dataArray.clear();
                     dataArray.append(byte);

                     checkSteps = CHECK_LENGTH;
                 }
            break;

            case CHECK_LENGTH:  //接收数据长度
                 dataArray.append(byte);
                 lengthCount++;
                 if(lengthCount == 1)
                 {
                     dataLength = (quint16)byte << 8;
                 }
                 if(lengthCount == 2)
                 {
                     lengthCount = 0;
                     dataLength |= byte;

                     checkSteps = CHECK_FUNCTION;
                 }
                 break;

            case CHECK_FUNCTION:   //接收数据功能
                 dataArray.append(byte);
                 lengthCount++;
                 if(lengthCount == 2)
                 {
                     lengthCount = 0;
                     checkSteps = CHECK_BODY;
                 }
            break;


            case CHECK_BODY:   //接收数据内容
                 dataArray.append(byte);
                 lengthCount++;
                 if(lengthCount >= dataLength)
                 {
                     lengthCount = 0;
                     checkSteps = CHECK_CHECKCODE;
                 }
            break;

            case CHECK_CHECKCODE:  //检查数据校验
                 quint8 checkCode = 0;
                 for(int i=1; i<dataArray.size(); i++)
                 {
                     checkCode ^= dataArray.at(i);
                 }
                 if(checkCode == byte)
                 {
                     dataArray.append(byte);
                     Package package;
                     package.setHead(dataArray.mid(0,1));
                     package.setLength(dataLength);
                     package.setFunction(dataArray.mid(3,2).toHex().toInt(0,16));
                     package.setBody(dataArray.mid(5,dataLength));
                     package.setCheckCode(checkCode);
                     packageList.append(package);
                     isParseSucceed = true;
                 }
                 checkSteps = CHECK_HEAD;
            break;
        }
    }
    if(!isParseSucceed)
    {

        QJson::Parser parser;
        bool isOK;
        QVariantMap jsonData = parser.parse(data, &isOK).toMap();

        if (isOK)
        {
            QString type = jsonData["type"].toString();
            if(type == "REQUEST_TCP")
            {
                Package package;
                package.setFunction(0x0000);
                packageList.append(package);
                qDebug()<<"set 0x00";
            }
        }
    }
    return packageList;
}

QByteArray GowildProtocol::generateData(Package package)
{
    QByteArray data;

    quint16 functionCode = package.function();
    if(functionCode != 0)
    {
        quint16 bodyLength = package.body().size();
        data.append(0xAA);
        data.append(DataTypeConver::intToByteArray(bodyLength,2));
        data.append(DataTypeConver::intToByteArray(functionCode,2));
        data.append(package.body());

        quint8 checkCode = 0;
        for(int i=1; i<data.size(); i++)
        {
            checkCode ^= data.at(i);
        }
        data.append(checkCode);
    }
    else
    {
        data.append(package.body());
    }
    return data;
}
